package com.um2.simplexe.serveur.ui.util.controleUI.actionsGeneriques;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JOptionPane;

import com.um2.simplexe.serveur.ui.entryPoint.FenetreApplicationServeur;
import com.um2.simplexe.serveur.ui.util.controleUI.InformationsSurApplicationServeur;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.ChargeurLibrairie;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.menu.ControleurDeMenu;



/**
 * 
 * Dans le but d'avoir une interface unifiee,
 * il faut se mettre d'accord sur la taille de police,
 * les messages d'alerte,
 * les menus,...
 * 
 * Ici on a un acces centralise sur les fonction UI.
 * 
 * De plus cela evite les fautes d'orthographe,
 * car on n'a cas corriger chaque faute une seule fois .
 * 
 * @author jean-marie codol
 *
 */
public class Evenements {

	
	
	static int compteurDeFichiersTemporaires = 0 ;
	
	
	/**
	 * constructeur par defaut
	 *
	 */
	public Evenements() {
	}
	
	
	public static void quitterLAppli () {
		if (JOptionPane.OK_OPTION==JOptionPane.showConfirmDialog(
				FenetreApplicationServeur.getInstance(),
				"Quitter ?",
				"Quitter Simplexe",
				JOptionPane.YES_NO_OPTION))
			System.exit(0) ;
	}
	
	
	/*
	 * affiche une fenetre avec un warning, et un message.
	 */
	public static void warning(String message) {
		JOptionPane.showMessageDialog(null, message, "alerte", JOptionPane.WARNING_MESSAGE) ;
	}

	// on verifie si en local on a la derniere version du plugin
	// par rapport au serveur.
	public static void verifierSiDerniereVersionDesPluginsMenus(ControleurDeMenu i) {
		/*
		 * i contient une methode getURLFichierInfoDerniereVersion().
		 * cette methode permet de recuperer le fichier texte contenant
		 * le numero de la derniere version.
		 */
		if (i.getURLFichierInfoDerniereVersion()==null || i.getURLFichierInfoDerniereVersion()=="")
		{
			System.err.println("Evenements.java:verifierSiDerniereVersionDesPluginsMenus impossible:\n" +
					"pour le plugin chargeur de menu :"+i.getNomPlugin());
		}
		
		if (i.getVersionPlugin()==0)
		{
			// la version n'est pas renseignee
			System.err.println("version non renseignee pour :"+i.getNomPlugin()+" on continue sur le plugin suivant");
			return ;
		}
		
		
		URL url;
		try {
			url = new URL (i.getURLFichierInfoDerniereVersion());
		} catch (MalformedURLException e1) {
			System.err.println("impossible d'ouvrir l'URL (url mal formee)"+i.getURLFichierInfoDerniereVersion()+"\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
		
		/**
		 * on ouvre le flux comme un fichier
		 */
		InputStream is;
		try {
			is = url.openStream ();
		} catch (IOException e1) {
			System.err.println("impossible d'ouvrir l'URL (destination inaccessible)"+i.getURLFichierInfoDerniereVersion()+"\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
		
		// on cree un fichier temporaire dans le systeme.
		File destination;
		try {
			destination = File.createTempFile("SimplexeReseau"+compteurDeFichiersTemporaires,".buf");
		} catch (IOException e1) {
			System.err.println("impossible de creer le fichier temporaire\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
		compteurDeFichiersTemporaires++ ;
		// il sera supprime a la fin du programme
		destination.deleteOnExit();
		
		// Declaration des flux
        java.io.InputStream sourceFile=null;
        java.io.FileOutputStream destinationFile=null;
		
		
        
        // Creation du fichier temporaire:
        try {
			destination.createNewFile();
		} catch (IOException e) {
			System.err.println("impossible de creer un fichier temporaire\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
        
		// Ouverture du flux
        sourceFile = is ;
        try {
			destinationFile = new FileOutputStream(destination);
		} catch (FileNotFoundException e) {
			System.err.println("impossible d'ouvrir le flux reseau\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
		
		// Lecture par segment de 0.5Mo
		// on ecrit a la volee dans le fichier temporaire
        byte buffer[]=new byte[512*1024];
        int nbLecture;
        try {
			while( (nbLecture = sourceFile.read(buffer)) != -1 ) {
			        destinationFile.write(buffer, 0, nbLecture);
			}
		} catch (IOException e) {
			System.err.println("impossible d'ecrire dans le fichier temporaire\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
		
		
		// maintenant qu'on a bien ecrit,
		// on peut fermer les flux.
		try {
			sourceFile.close() ;
 	        destinationFile.close() ;
		} catch (IOException e) {
			System.err.println("impossible de fermer le fichier temporaire ou le flux reseau\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
		
		
		// maintenant on ouvre le fichier temporaire en lecture
		// l'objet File (destination) existe encore ,
		// le flux en ecriture a seulement ete ferme.
		// merci http://www.inf.enst.fr/~charon/coursJava/fichiersEtSaisies/lireFichierTexte.html
		
		BufferedReader lecteurAvecBuffer = null;
	    String ligne;
		
	    try {
			lecteurAvecBuffer = new BufferedReader (new FileReader(destination));
		} catch (FileNotFoundException e) {
			System.err.println("impossible d'ouvrir le fichier temporaire apres sa creation (contacter un developpeur)\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}

	    try {
	    	
	    	// on teste la version en comparant.
	    	boolean estLaDerniereVersion = true ;
	    	String URLRecupererDerniereVersion = null ;
			while ((ligne = lecteurAvecBuffer.readLine()) != null)
			{
					if (ligne.startsWith("version:"))
					{
						if (ligne.equals("version:"+i.getVersionPlugin()))
						{
							// la version est la bonne
						}else{
							// la version n'est pas la bonne !!!!
							System.err.println("la version pour "+i.getNomPlugin()+" est depassee ("+i.getVersionPlugin()+" alors que la "+ligne+"est disponible)");
							estLaDerniereVersion = false ;
						}
					}
					
					if (ligne.startsWith("url:"))
					{
						URLRecupererDerniereVersion = ligne.substring(4,ligne.length()) ;
					}
			}
			
			// il faut changer de version et on a l'adresse.
			// trop bien
			if (!estLaDerniereVersion && URLRecupererDerniereVersion!=null)
			{
				TelechargerPluginEtCharger(i,URLRecupererDerniereVersion) ;
			}else
			{
				System.out.println("on est a la derniere version du plugin "+i.getNomPlugin());
			}
			
			
		} catch (IOException e) {
			System.err.println("impossible de lire le fichier temporaire apres sa creation\n lors de la recuperation des informations de version sur "+i.getNomPlugin());
			return ; 
		}
		
	    try {
			lecteurAvecBuffer.close();
		} catch (IOException e) {
			// c'est pas grave, ce sera ferme a la fin de l'execution du programme.lol
			return ; 
		}
		
        
        
		
	}


	private static void TelechargerPluginEtCharger(ControleurDeMenu i,String adresse) {
		// on telecharge le .jar dans le repertoire pour les plugins.
		
		// pour le debut,c'est le meme que la methode verifierSiDerniereVersionDesPluginsMenus
		URL url;
		try {
			url = new URL (adresse);
		} catch (MalformedURLException e1) {
			System.err.println("impossible d'ouvrir l'URL (url mal formee)"+adresse);
			return ; 
		}
		
		/**
		 * on ouvre le flux comme un fichier
		 */
		InputStream is;
		try {
			is = url.openStream ();
		} catch (IOException e1) {
			System.err.println("impossible d'ouvrir l'URL (destination inaccessible)"+adresse);
			return ; 
		}
		
		// le fichier du plugin en .jar.new
		File f = new File(InformationsSurApplicationServeur.cheminVersPlugins+java.io.File.separatorChar+i.getNomPlugin()+".jar.new") ;
		
		
		// ici il existe
		// on le supprime.
		if (f.exists())
		{
		if (!f.delete())
		{
			System.err.println("la supression du plugin de "+i.getNomPlugin()+" (extention .jar.new) obselete a echoue "+f.getAbsolutePath());
			return ;
		}
		}
		
		// ici le fichier .jar.new n'existe plus.		
		
		// on le remplace par celui qu'on telecharge.
        // Creation du fichier temporaire:
        try {
			if (f.createNewFile())
			{}else 
			{
				System.err.println("impossible de creer le fichier .jar (plugins) pour le plugin "+i.getNomPlugin()) ;
			}
		} catch (IOException e) {
			System.err.println("impossible de creer le fichier .jar (plugins) pour le plugin "+i.getNomPlugin()+"\n :"+e.getMessage());
			return ; 
		}
	
        java.io.FileOutputStream destinationFile=null;
        try {
			destinationFile = new FileOutputStream(f);
		} catch (FileNotFoundException e) {
			System.err.println("impossible d'ouvrir le flux en ecriture pour ecrire le plugin (.jar) "+i.getNomPlugin());
			return ; 
		}

		// Lecture par segment de 0.5Mo
		// on ecrit a la volee dans le fichier jar
        byte buffer[]=new byte[512*1024];
        int nbLecture;
        try {
			while( (nbLecture = is.read(buffer)) != -1 ) {
			        destinationFile.write(buffer, 0, nbLecture);
			}
		} catch (IOException e) {
			System.err.println("impossible d'ecrire dans le fichier jar plugins de "+i.getNomPlugin());
			return ; 
		}
	
		// maintenant qu'on a bien ecrit,
		// on peut fermer les flux.
		try {
			is.close() ;
 	        destinationFile.close() ;
		} catch (IOException e) {
			System.err.println("impossible de fermer le fichier plugin "+i.getNomPlugin());
			return ; 
		}
		
		chargerUnSimpleJar(f.getAbsolutePath()) ;
		
	}


	private static void chargerUnSimpleJar(String absolutePath) {
		// ce n 'est pas un jar.
		if (!absolutePath.endsWith(".jar"))
		{
			System.err.println("on veut charger un jar dont l'extention n'est pas .jar :"+absolutePath);
			return ;
		}
		
		
		// le chargeur de librairie
		ChargeurLibrairie chargeurDeLib = new ChargeurLibrairie() ;
		
		// on lui donne a manger la liste des fichiers potentiellement plugins
		chargeurDeLib.setFiles(new String[] {absolutePath}) ;
		
		
		try {
			chargeurDeLib.chargerToutLesPlugins() ;
		} catch (Exception e) {
			Evenements.warning("erreur dans le chargement de la librairie "+absolutePath+": "+e.getMessage());
		} ;

		
	}
}
